﻿#pragma once

#include <iostream>
#include <thread>
#include <mutex>
#include <QString>
#include "../task/YTools.h"

struct AVFormatContext;
struct AVCodecParameters;
struct AVPacket;
struct AVCodecContext;
struct YRational
{
	int num; ///< Numerator
	int den; ///< Denominator
};

/// <summary>
/// 封装及解封装器基类
/// </summary>
class YBaseMuxer
{

public:
	/// <summary>
	/// 将输入的编解码参数复制到输出的编解码参数中
	/// </summary>
	/// <param name="stream_index">输入流的index，用于区分是音频流还是视频流</param>
	/// <param name="dst">输出参数</param>
	bool CopyInCodecParametersToOut(int stream_index, AVCodecParameters* dst);

	bool CopyParaParameters(int stream_index, AVCodecContext* dts);

	/// <summary>
	/// 设置封装上下文
	/// </summary>
	/// <param name="c"></param>
	void setContext(AVFormatContext* c);
	/// <summary>
	/// 清理资源
	/// </summary>
	void Close();
	//获取音频索引
	int GetAudioIndex() {
		return audio_index;
	}
	//获取视频流索引
	int GetVideoIndex() {
		return video_index;
	}
	YRational GetVideoTimeBase()
	{
		return video_timebase;
	}
	YRational GetAudioTimeBase()
	{
		return audio_timebase;
	}

	int GetVideoWidth()
	{
		return videoWidth;
	}
	int GetVideoHeight()
	{
		return videoHeight;
	}
	//根据timebase换算时间
	bool RescaleTime(AVPacket* pkt, long long offset_pts, YRational time_base);

	//根据timebase换算时间
	bool RescaleTime(AVPacket* pkt, long long offset_pts, AVRational* time_base);

	//把pts dts duration 值转为毫秒
	long long RescaleToMs(long long pts, int index);

	//打印错误信息
	void PrintError(int err, QString msg);

	int GetVideoCodecId() {
		return video_codec_id;
	}

	//返回智能指针 复制视频参数
	std::shared_ptr<YAVParameters> CopyVideoParameters();
	//返回智能指针 音频参数
	std::shared_ptr<YAVParameters> CopyAudioParameters();

	//判断是否超时
	bool IsTimeout()
	{
		if (NowMs() - last_time_ > time_out_ms_) //超时
		{
			last_time_ = NowMs();
			is_connected_ = false;
			return true;
		}

		return false;
	}

	//设定超时时间
	void set_time_out_ms(int ms);

	bool is_connected() { return is_connected_; }

	//获取视频时间基
	YBaseMuxer();
	~YBaseMuxer();
protected:
	AVFormatContext* c_context = nullptr;
	std::mutex mutex;
	int audio_index = 1;
	int video_index = 0;
	YRational video_timebase = { 1,25 };
	YRational audio_timebase = { 1,9000 };
	int video_codec_id;
	int videoWidth = 0;
	int videoHeight = 0;

	int time_out_ms_ = 0;           //超时时间 毫秒
	long long last_time_ = 0;       //上次接收到数据的时间
	bool is_connected_ = false;     //是否连接成功


};
